var love
import car_data from "../data/car.js"
export default class car{
  constructor(_love,type = 0,upgradeData = {}){
    love = love || _love
    this.texture = love.loader.data.sheet.extend()
    this.data = car_data[type]
    this.texture.setQuad(...this.data.quad)
    this.texture.setAnchorCenter()
    this.lap = 1
    this.x = 0
    this.dx = 0
    this.y = 0
    this.dy = 0
    this.rot = 0
    this.dr = 0
    this.dir = 1
    this.scale = 4
    this.w = 24*this.scale
    this.h = 16*this.scale
    this.n2oConsume = 0.03
    this.fuelConsume = 0.001
    this.upgrade(upgradeData)

    this.speed = 0
    this.tour = 0
    this.pos = 400
    this.coin = 0
    this.buff = []
  }
  upgrade(up){
    let data = this.data
    this.hpMax = Math.floor(100 + 50*(data.structure[0] + up.structure || 0 ))
    this.hp = this.hpMax

    this.fuelMax = Math.floor(100 + 20*(data.fueltank[0] + up.fueltank || 0))
    this.fuel = this.fuelMax

    this.n2oMax = 100 + 30 * (data.n2ovol[0] +  up.n2ovol || 0)
    this.n2o = this.n2oMax
    this.n2oPower = 0.01 + 0.0015 * (data.n2opower[0] + up.n2opower || 0)
    this.n2oGen = this.n2oMax/1000

    this.damping = 0.03 - 0.002 * (data.streamline[0] + up.streamline || 0) 
    this.dampingSpeedRate = 0.2 - 0.015 * (data.streamline[0] + up.streamline || 0)
    this.shiftTime = 800 - 60 * (data.streamline[0] + up.streamline || 0)

    this.power = 0.04 + 0.002 * (data.enginepower[0] + up.enginepower || 0)

    this.itemEffect = 1.2 ^ (data.itemslot[0] + up.itemslot || 0)

  }
  setToRoad(isPlayer,road,lap = 1,tour = 0,dir = 1,speed = 0){
    this.road = road
    if (isPlayer) {
      road.playerCar = this
    }
    this.isPlayer = isPlayer
    this.lap = lap
    this.tour = tour
    this.dir = dir
    this.y = this.getLapY(this.lap)
    this.speed = speed
  }
  getLapY(lap){
    return this.road.getLapPos.bind(this.road)(lap)
  }
  changeLap(lap){
    if (!this.moving && lap>0 && lap<=this.road.lapCount){
      let tar = this.n2o + 0.2 * this.n2oMax < this.n2oMax ? this.n2o + 0.2 * this.n2oMax : this.n2oMax
      love.timer.newTween(
        this.shiftTime, this, { y: this.getLapY(lap), n2o: tar }, "Quadratic.Out",
        function () {
          this.moving = false
          this.lap = lap
        }.bind(this)
      )
      this.moving = true
      this.speed = this.speed - this.damping * this.speed * this.dampingSpeedRate * 20
    }
  }
  control(touch) {
    if (this.lostCtrl){return}
    if (touch.dy > 0 ) {
      this.changeLap(this.lap + 1)
    } else if (touch.dy < 0 ) {
      this.changeLap(this.lap - 1)
    } 
    if (touch.dx == 0 && touch.dy == 0) {
      this.holding = true
    }
  }
  addBuff(type,time){
    let buff = {type:type,time:time}
    this.buff.push(buff)
  }
  updateBuff(dt){
    let newBuff = []
    this.buffAcc = 0
    this.unbreakable = false
    this.unstopable = false
    this.fireable = false
    for (var i in this.buff) {
      let buff = this.buff[i]
      buff.time = buff.time - dt
      if (buff.time>0) {
        switch(buff.name){
          case "acc":
            this.buffAcc += 0.01
            break
          case "unbreakable":
            this.unbreakable = true
            break
          case "unstopable":
            this.unstopable = true
            break
          case "fireable":
            this.fireable = true
            break
        }
        newBuff.push[buff]
      }
    }
    this.buff = newBuff
  }

  updateN2O(dt){
    this.n2oAcc = 0
    if (this.holding) {
      this.addN2O(- dt * 0.05)
      if (this.n2o > 0) {
        this.n2oAcc = this.n2oPower
        this.n2o -= this.n2oConsume*dt
        love.particle.newParticle({
          x: this.x - 12 * this.scale,
          y: this.y + love.math.random(-5, 5),
          life: 1500,
          dx: [-0.2, -0.7],
          dy: [-0.05, 0.05],
          sx: 0.95,
          ds: 0.2,
          da: -0.02,
          color: { r: 0, g: 0, b: 0, a: 1 }
        })
      } 
    } else {
      this.addN2O(this.n2oGen)
    }
    this.holding = false
  }

  syncPos(dt){
    if (!this.isPlayer) {
      this.pos = this.road.playerCar.pos + (this.tour - this.road.playerCar.tour)
      if (this.pos > 5000 || this.pos < - 2000) {
        this.destroyed = true
      }
      this.x = this.pos

    } else {
      this.x = this.pos * (Math.random() * 0.01 + 0.99)
      this.fuel -= this.fuelConsume * dt
      if (this.fuel <= 0 || this.hp <= 0) {
        return love.switch("gameover",Math.floor(this.tour / 3600) / 10)
      }
    }

    if (this.lostCtrl) {
      this.x = this.x + this.dx
      this.y = this.y + this.dy
      this.rot = this.rot + this.dr
    }

  }
  update(dt){ 
    this.updateN2O(dt)
    this.syncPos(dt)
    this.updateBuff(dt)

    this.speed = this.speed + (this.lostPower ? 0 : 1)*(this.power + this.n2oAcc + this.buffAcc - this.damping) - this.damping * this.speed * this.dampingSpeedRate
    this.tour = this.tour + this.speed * dt
  }
  draw(){
    love.graphics.setColor("#FFFFFF")
    love.graphics.draw(this.texture,this.x,this.y,this.rot,this.scale*this.dir,this.scale)
    //console.log(this.texture, this.x, this.y, 0, this.scale, this.scale)
  }
  checkColl(self,that){
    if(that.lostCtrl){return}
    let dx = that.x - self.x
    let dy = that.y - self.y
    if (Math.abs(dx) < self.w / 2 && Math.abs(dy) < self.h/2){
      return {dx : dx,dy : dy,
      cx : (self.x+that.x)/2,cy:(self.y + that.y)/2}
    } 
  }
  throwAway(dir){
    this.dr = 0.3
    this.dx = dir.dx*0.2
    this.dy = dir.dy*0.2
    this.lostCtrl = true
    love.timer.delay(1000,function(){
      this.destroyed = true
    }.bind(this))
  }

  crash(){
    this.dr = 0.3
    this.speed *= 0.2
    this.lostCtrl = true
    love.timer.delay(3000, function () {
      this.destroyed = true
      this.lostCtrl = false
      this.rot = 0
    }.bind(this))
  }


  addN2O(c){
    if (this.n2o + c> this.n2oMax) {
      this.n2o = this.n2oMax
    } else if (this.n2o + c<0){
      this.n2o = 0
    } else {
      this.n2o += c
    }
  }

  addHP(c){
    if (this.hp + c > this.hpMax) {
      this.hp = this.hpMax
    } else if (this.hp + c < 0) {
      this.hp = 0
    } else {
      this.hp += c
    }
  }
}